/*
 * @Author: lei
 * @Description: 信号量的一个简易实现，利用互斥量和条件变量
 * @FilePath: /threadpool2/semaphore.cc
 */
// compile: g++ -o semaphore semaphore.cc -std=c++14
// run: ./semaphore
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>

class Semaphore {
 public:
  Semaphore(int init_rlimit = 0) : rlimit_(init_rlimit) {}
  ~Semaphore() = default;
  void Wait();  // P操作
  void Post();  // V操作

 private:
  std::atomic_int rlimit_;
  std::mutex mutex_;
  std::condition_variable cond_;
};
void Semaphore::Wait() {
  // std::unique_lock<std::mutex> ul; 同样的错误你要犯几遍？？？
  std::unique_lock<std::mutex> ul(mutex_);
  cond_.wait(ul, [&]() -> bool { return rlimit_ > 0; });
  rlimit_--;
}
void Semaphore::Post() {
  std::unique_lock<std::mutex> ul(mutex_);
  cond_.notify_one();
  rlimit_++;
}
Semaphore sem(0);
void Test1() {
  std::cout << "----------Test1 begin----------" << std::endl;
  std::thread t1([&]() {
    std::cout << "----------thread1 begin----------" << std::endl;
    std::cout << "thread1_id: " << std::this_thread::get_id() << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    sem.Post();
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "----------thread1 end----------" << std::endl;
  });
  t1.detach();
  std::cout << "----------Test1 end----------" << std::endl;
}
void Test2() {
  std::cout << "----------Test2 begin----------" << std::endl;
  sem.Wait();
  std::cout << "----------Test2 end----------" << std::endl;
}
int main() {
  Test1();
  Test2();
  return 0;
}
